﻿using System;
using System.IO;
using System.Runtime.InteropServices;
using daq_test_cs;
using static daq_test_cs.DAQ125Wrapper;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MultiDeviceDemo;

public static class IntPtrExtensions
{
    public static byte[] IntPtrToByteArray(IntPtr ptr, int length)
    {
        var array = new byte[length];
        Marshal.Copy(ptr, array, 0, length);
        return array;
    }
}

public class Program
{
    /// <summary>
    /// 单机采集功能
    /// </summary>
    public static void SingleDeviceCollection()
    {
        Console.WriteLine("=== 单机采集模式 ===");
        
        var device = DAQ125Wrapper.DAQ125_New();
        var usb_server = USBServerWrapper.USBServer_New(USBServerWrapper.DeviceType.DeviceType_DAQ125);
        if (usb_server == IntPtr.Zero)
        {
            Console.WriteLine("USB服务器初始化失败");
            return;
        }
        
        // 获取设备总数
        uint deviceCount = USBServerWrapper.USBServer_GetDeviceCount(usb_server);
        Console.WriteLine($"发现 {deviceCount} 个设备");

        try
        {
            if(deviceCount == 0)
            {
                Console.WriteLine("未发现设备");
                return;
            }
            
            // 使用第一个设备
            var socket = USBServerWrapper.USBServer_GetClientByIndex(usb_server, 0);
            if (socket == IntPtr.Zero)
            {
                Console.WriteLine("获取设备失败");
                return;
            }

            if (!DAQ125Wrapper.DAQ125_UseBackend(device, socket))
            {
                Console.WriteLine("使用后端失败");
                return;
            }

            if (!DAQ125Wrapper.DAQ125_InitializeDevice(device))
            {
                Console.WriteLine("初始化设备失败");
                return;
            }

            if (!DAQ125Wrapper.DAQ125_ConnectedDevice(device))
            {
                Console.WriteLine("连接设备失败");
                return;
            }

            Console.WriteLine("已连接到设备");
            
            // 获取设备信息
            GetSingleDeviceInfo(device);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"设备连接过程中发生错误: {ex.Message}");
            return;
        }

        // 配置设备参数
        ConfigureSingleDevice(device);

        // 开始采集
        if(!DAQ125_StartCollection(device)){
            Console.WriteLine("开始采集失败");
            return;
        }

        Console.WriteLine("开始采集成功");
        Thread.Sleep(100);

        // 软件触发
        if(!DAQ125_ConfigADCTriggerSource(device)){
            Console.WriteLine("软件触发失败");
            return;
        }

        Console.WriteLine("软件触发成功");

        // 采集数据
        CollectSingleDeviceData(device);

        // 停止采集
        if(!DAQ125_StopCollection(device)){
            Console.WriteLine("停止采集失败");
        }
        else
        {
            Console.WriteLine("停止采集成功");
        }

        // 清理资源
        DAQ125Wrapper.DAQ125_Delete(device);
        USBServerWrapper.USBServer_Delete(usb_server);
    }

    /// <summary>
    /// 获取单个设备信息
    /// </summary>
    private static void GetSingleDeviceInfo(IntPtr device)
    {
        // 获取设备名称
        System.Text.StringBuilder nameBuffer = new System.Text.StringBuilder(256);
        if (DAQ125Wrapper.DAQ125_SystemOpGetDeviceName(device, nameBuffer, 256))
        {
            Console.WriteLine($"设备名称: {nameBuffer.ToString()}");
        }
        
        // 获取设备类别
        if (DAQ125Wrapper.DAQ125_BasicInfoGetDeviceType(device))
        {
            System.Text.StringBuilder typeBuffer = new System.Text.StringBuilder(256);
            if (DAQ125Wrapper.DAQ125_GetDeviceType(device, typeBuffer, 256))
            {
                Console.WriteLine($"设备类别: {typeBuffer.ToString()}");
            }
        }
        
        // 获取硬件版本
        if (DAQ125Wrapper.DAQ125_BasicInfoGetHardwareVersion(device))
        {
            System.Text.StringBuilder hwVersionBuffer = new System.Text.StringBuilder(256);
            if (DAQ125Wrapper.DAQ125_GetHardwareVersion(device, hwVersionBuffer, 256))
            {
                Console.WriteLine($"硬件版本: {hwVersionBuffer.ToString()}");
            }
        }
        
        // 获取软件版本
        if (DAQ125Wrapper.DAQ125_BasicInfoGetSoftwareVersion(device))
        {
            System.Text.StringBuilder swVersionBuffer = new System.Text.StringBuilder(256);
            if (DAQ125Wrapper.DAQ125_GetSoftwareVersion(device, swVersionBuffer, 256))
            {
                Console.WriteLine($"软件版本: {swVersionBuffer.ToString()}");
            }
        }
        
        // 获取SN
        if (DAQ125Wrapper.DAQ125_ProductTestGetSN(device))
        {
            Thread.Sleep(200);
            System.Text.StringBuilder snBuffer = new System.Text.StringBuilder(256);
            if (DAQ125Wrapper.DAQ125_GetSN(device, snBuffer, 256))
            {
                Console.WriteLine($"设备序列号(SN): {snBuffer.ToString()}");
            }
        }
    }

    /// <summary>
    /// 配置单个设备参数
    /// </summary>
    private static void ConfigureSingleDevice(IntPtr device)
    {
        Console.WriteLine("开始配置设备参数...");

        // 配置触发模式
        int triggerType = (int)LockzhinerADCTriggerType.RisingEdge;
        int triggerMode = (int)LockzhinerADCTriggerMode.Common;
        int triggerChannel = (int)LockzhinerADCChannel.ADCChannelAINNone;
        int triggerLevel = 300;
        bool result_TriggerType = DAQ125Wrapper.DAQ125_ConfigADCTrigger(device, triggerType, triggerMode, triggerChannel, triggerLevel);
        Console.WriteLine(result_TriggerType ? "ADC触发配置成功" : "ADC触发配置失败");

        // 配置采样率
        int sampleRate = (int)LockzhinerADCSampleRate.ADCSampleRate_800_K;
        bool result_SampleRate = DAQ125Wrapper.DAQ125_ConfigADCSampleRate(device, sampleRate);
        Console.WriteLine(result_SampleRate ? "采样率配置成功" : "采样率配置失败");

        // 配置电压量程
        int adcVoltage = (int)LockzhinerADCVoltage.ADCVoltage_10_V;
        bool result_ADCVoltage = DAQ125Wrapper.DAQ125_ConfigADCVoltage(device, adcVoltage);
        Console.WriteLine(result_ADCVoltage ? "电压量程配置成功" : "电压量程配置失败");

        // 配置触发长度
        uint triggerLength = 49600;
        bool result_TriggerLength = DAQ125Wrapper.DAQ125_ConfigADCTriggerLength(device, triggerLength);
        Console.WriteLine(result_TriggerLength ? "触发长度配置成功" : "触发长度配置失败");
        
        // 配置触发超时
        uint triggerTimeout = 100;
        bool result_TriggerTimeout = DAQ125Wrapper.DAQ125_ConfigTriggerTimeout(device, triggerTimeout);
        Console.WriteLine(result_TriggerTimeout ? "触发超时配置成功" : "触发超时配置失败");

        // 配置ADC通道
        byte adcChannel = 0b11111111;
        bool result_ADCChannel = DAQ125Wrapper.DAQ125_ConfigADCChannel(device, adcChannel);
        Console.WriteLine(result_ADCChannel ? "ADC通道配置成功" : "ADC通道配置失败");

        // 配置ACDC模式
        byte acdcMode = 1;
        bool result_ACDCMode = DAQ125Wrapper.DAQ125_ConfigACDC(device, acdcMode);
        Console.WriteLine(result_ACDCMode ? "ACDC模式配置成功" : "ACDC模式配置失败");
    }

    /// <summary>
    /// 采集单个设备数据
    /// </summary>
    private static void CollectSingleDeviceData(IntPtr device)
    {
        uint readSize = 49600;
        byte adcChannel = 0b11111111;
        float[][] channelData = new float[8][];
        for (int i = 0; i < 8; i++)
        {
            channelData[i] = new float[readSize];
        }

        Console.WriteLine("开始读取数据...");
        
        using (var cts = new CancellationTokenSource())
        {
            var tasks = new Task[8];
            for (byte channel = 0; channel < 8; channel++)
            {
                if ((adcChannel & (1 << channel)) != 0)
                {
                    byte currentChannel = channel;
                    tasks[channel] = Task.Run(() =>
                    {
                        bool readSuccess = false;
                        int retryCount = 0;
                        int maxRetries = 10;
                        
                        while (!readSuccess && !cts.Token.IsCancellationRequested && retryCount < maxRetries)
                        {
                            readSuccess = DAQ125_TryReadData_Batch(device, currentChannel, channelData[currentChannel], readSize);
                            if (readSuccess)
                            {
                                int validDataCount = channelData[currentChannel].Count(x => x != 0);
                                Console.WriteLine($"通道 {currentChannel + 1} 数据读取成功");
                                Console.WriteLine($"通道 {currentChannel + 1} 总数据长度: {readSize}");
                                Console.WriteLine($"通道 {currentChannel + 1} 非零数据长度: {validDataCount}");
                                
                                // 打印前5个数据点作为示例
                                Console.WriteLine($"通道 {currentChannel + 1} 的前5个数据点:");
                                for (int i = 0; i < Math.Min(5, readSize); i++)
                                {
                                    Console.WriteLine($"数据点 {i}: {channelData[currentChannel][i]:F3}V");
                                }
                            }
                            else
                            {
                                retryCount++;
                                Thread.Sleep(100);
                            }
                        }
                        
                        if (!readSuccess)
                        {
                            Console.WriteLine($"通道 {currentChannel + 1} 数据读取失败，已达到最大重试次数");
                        }
                    }, cts.Token);
                }
            }

            Console.WriteLine("数据采集中，按任意键停止...");
            Console.ReadKey();
            
            cts.Cancel();
            
            try
            {
                Task.WaitAll(tasks.Where(t => t != null).ToArray());
            }
            catch (AggregateException)
            {
                // 忽略取消导致的异常
            }
        }
    }

    /// <summary>
    /// 多机采集功能
    /// </summary>
    public static void MultiDeviceCollection()
    {
        Console.WriteLine("=== 多机采集模式 ===");
        
        DeviceManager manager = new DeviceManager();

        try
        {
            // 初始化USB服务器
            if (!manager.InitializeServer())
            {
                Console.WriteLine("初始化USB服务器失败");
                return;
            }

            // 发现设备
            int deviceCount = manager.DiscoverDevices();
            if (deviceCount == 0)
            {
                Console.WriteLine("未发现设备");
                return;
            }

            Console.WriteLine($"成功连接 {deviceCount} 个设备");

            // 配置所有设备
            if (!manager.ConfigureAllDevices(
                triggerType: LockzhinerADCTriggerType.RisingEdge,
                triggerMode: LockzhinerADCTriggerMode.Common,
                triggerChannel: LockzhinerADCChannel.ADCChannelAINNone,
                triggerLevel: 300,
                sampleRate: LockzhinerADCSampleRate.ADCSampleRate_800_K,
                voltage: LockzhinerADCVoltage.ADCVoltage_10_V,
                triggerLength: 49600,
                triggerTimeout: 100,
                adcChannel: 0b11111111,
                acdcMode: 1))
            {
                Console.WriteLine("警告：某些设备配置失败，但程序将继续执行");
            }

            // 启动所有设备采集
            if (!manager.StartAllCollection())
            {
                Console.WriteLine("警告：某些设备启动采集失败，但程序将继续执行");
            }

            // 开始数据读取任务
            manager.StartDataReadingTasks(0b11111111, 49600);

            Console.WriteLine("\n所有设备正在采集数据...");
            Console.WriteLine("按任意键停止采集并保存数据");
            Console.ReadKey();

            // 停止所有设备采集
            manager.StopAllCollection();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"多机采集过程中发生错误: {ex.Message}");
            Console.WriteLine(ex.StackTrace);
        }
        finally
        {
            manager.Dispose();
        }
    }

    /// <summary>
    /// 显示主菜单
    /// </summary>
    private static void ShowMainMenu()
    {
        Console.WriteLine("\n=== DAQ125 数据采集系统 ===");
        Console.WriteLine("1. 单机采集模式");
        Console.WriteLine("2. 多机采集模式");
        Console.WriteLine("3. 退出程序");
        Console.WriteLine("============================");
        Console.Write("请选择功能 (1-3): ");
    }

    public static void Main(string[] args)
    {
        Console.WriteLine("DAQ125 数据采集系统启动");
        
        while (true)
        {
            ShowMainMenu();
            
            string input = Console.ReadLine();
            
            switch (input)
            {
                case "1":
                    try
                    {
                        SingleDeviceCollection();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"单机采集执行失败: {ex.Message}");
                    }
                    break;
                    
                case "2":
                    try
                    {
                        MultiDeviceCollection();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"多机采集执行失败: {ex.Message}");
                    }
                    break;
                    
                case "3":
                    Console.WriteLine("程序退出");
                    return;
                    
                default:
                    Console.WriteLine("无效选择，请重新输入");
                    break;
            }
            
            Console.WriteLine("\n按任意键返回主菜单...");
            Console.ReadKey();
            Console.Clear();
        }
    }
}